{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 特殊属性和方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `__file__`\n",
    "\n",
    "脚本执行的完整路径\n",
    "\n",
    "### `__name__` \n",
    "\n",
    "* 当用python test.py，则文件的`__name__`为`'__main__'`  \n",
    "* 当脚本作为模块时，用python -m test.py，则文件的`__name__`为`'test'`\n",
    "\n",
    "### 文件夹下的`__main__.py` 和 `__init__.py`\n",
    "    python3 xxx.py\n",
    "    python3 -m xxx.py\n",
    "\n",
    "这是两种加载py文件的方式:\n",
    "1. 叫做直接运行\n",
    "2. 相当于import,叫做当做模块来启动，前提是已加入sys.path\n",
    "\n",
    "python 将一个文件夹作为 package 对待，那么这个文件夹中必须包含一个名为 `__init__.py` 的文件，即使它是空的  \n",
    "如果你需要 python 将一个文件夹作为 package 执行，那么这个文件夹中必须包含一个名为 `__main__.py` 的文件\n",
    "\n",
    "\n",
    "### `__all__`\n",
    "\n",
    "对于from ModuleName import * 这种形式，要特别注意重名现象。\n",
    "\n",
    "Python中，对于一个模块，具有一个名为 `__all__`的属性，该属性的值就是被from ModuleName import *这样的语句绑定的属性列表；否则，这种类型的from语句将绑定模块中除了以下划线开始的属性（私有属性）外的所有属性。这样的话，对于同一个名空间里 面出现重名现象的概率就加大了，为了减少这种情况的发生，都会在模块开始处定义`__all__`属性的内容，写出可以被这种from类型导入的属性\n",
    "下面的是os.py里面的一段代码：\n",
    "\n",
    "    __all__ = [\"altsep\", \"curdir\", \"pardir\", \"sep\", \"pathsep\", \"linesep\",\"defpath\", \"name\", \"path\", \"devnull\"]\n",
    "\n",
    "### 其他\n",
    "\n",
    "    __globals__: global namespace in which this function was defined\n",
    "    __file__: filename (missing for built-in modules)\n",
    "\n",
    "### 内建特殊属性\n",
    "用`dir(__builtins__)`查看内建特殊属性，特殊属性都是以双下划线开头和结尾\n",
    "\n",
    "    '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__'\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类属性调用原理\n",
    "| 目的 | 所编写代码 | Python 实际调用\n",
    "| :---: | :---:|\n",
    "| 类构造器 | x = MyClass() | `x.__new__()`\n",
    "| 类析构器 | del x | `x.__del__()`\n",
    "| 只定义特定集合的某些属性 || `x.__slots__()`\n",
    "| 自定义散列值 | hash(x) | `x.__hash__()`\n",
    "| 获取某个属性的值 | x.color | `type(x).__dict__['color'].__get__(x, type(x))`\n",
    "| 设置某个属性的值 | x.color = 'PapayaWhip' | `type(x).__dict__['color'].__set__(x, 'PapayaWhip')`\n",
    "| 删除某个属性 | del x.color | `type(x).__dict__['color'].__del__(x)`\n",
    "| 控制某个对象是否是该对象的实例 | isinstance(x, MyClass) | `MyClass.__instancecheck__(x)`\n",
    "| 控制某个类是否是该类的子类 | issubclass(C, MyClass) | `MyClass.__subclasscheck__(C)`\n",
    "| 控制某个类是否是该抽象基类的子类 | issubclass(C, MyABC) | `MyABC.__subclasshook__(C)`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `__new__(cls, [...)`\n",
    "`__new__` 是在一个对象实例化的时候所调用的第一个方法。它的第一个参数是这个类，其他的参数是用来直接传递给 `__init__` 方法。 `__new__` 方法相当不常用,但是它有自己的特性，特别是当继承一个不可变的类型比如一个tuple或者string。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `__init__(self, […)`\n",
    "此方法为类的初始化方法。当构造函数被调用的时候的任何参数都将会传给它。\n",
    "> 调用 x = SomeClass(10, 'foo')，那么 __init__ 将会得到两个参数10和foo。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `__del__(self)`\n",
    "如果 `__new__` 和 `__init__` 是对象的构造器的话，那么 `__del__` 就是析构器。它不实现语句 del x (以上代码将不会翻译为 `x.__del__()` )。它定义的是当一个对象进行垃圾回收时候的行为。当一个对象在删除的时需要更多的清洁工作的时候此方法会很有用，比如套接字对象或者是文件对象。注意，如果解释器退出的时候对象还存存在，就不能保证 `__del__` 能够被执行，所以 `__del__` can’t serve as a replacement for good coding practices ()~~~~~~\n",
    "\n",
    "[特殊属性调用机制](http://dipyzh.bitbucket.org/special-method-names.html)"
   ]
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4rc1"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": "15",
    "lenType": "10",
    "lenVar": "60"
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
